﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Mail;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Security.Cryptography;
using System.IO;
using System.Web;
using System.Data.Entity;
using System.Drawing;
using System.Drawing.Imaging;

namespace Business
{
    public static class Common
    {

        /// <summary>
        /// sending mail
        /// </summary>
        public static void SendMail(string subject, string to, string body)
        {
            try
            {
                MailMessage mail = new MailMessage();
                SmtpClient SmtpServer = new SmtpClient();
                FosIntelEntities entity = new FosIntelEntities();
                // getting setting from setting table
                List<fos_Setting> emailSettings = (from a in entity.fos_Setting select a).ToList<fos_Setting>();
                fos_Setting emailHost = emailSettings.Where(a => a.Id == 4).FirstOrDefault();
                fos_Setting emailPort = emailSettings.Where(a => a.Id == 5).FirstOrDefault();
                fos_Setting username = emailSettings.Where(a => a.Id == 6).FirstOrDefault();
                fos_Setting password = emailSettings.Where(a => a.Id == 7).FirstOrDefault();
                fos_Setting From = emailSettings.Where(a => a.Id == 2).FirstOrDefault();
                SmtpServer.Host = emailHost.ParamValue;
                SmtpServer.Port = Convert.ToInt32(emailPort.ParamValue);


                SmtpServer.Credentials = new System.Net.NetworkCredential(username.ParamValue, password.ParamValue);
                mail.From = new MailAddress(From.ParamValue);
                mail.IsBodyHtml = true;

                mail.To.Add(to);
                mail.Subject = subject;
                mail.Body = body;


                SmtpServer.EnableSsl = true;

                SmtpServer.Send(mail);

            }
            catch (Exception ex)
            {
                throw new Exception("Mail Server Error!" + ex.Message);
            }
        }


        public static void SendMail(string subject, List<string> to, string body)
        {
            try
            {
                MailMessage mail = new MailMessage();
                SmtpClient SmtpServer = new SmtpClient();
                FosIntelEntities entity = new FosIntelEntities();
                // getting setting from setting table
                List<fos_Setting> emailSettings = (from a in entity.fos_Setting select a).ToList<fos_Setting>();
                fos_Setting emailHost = emailSettings.Where(a => a.Id == 4).FirstOrDefault();
                fos_Setting emailPort = emailSettings.Where(a => a.Id == 5).FirstOrDefault();
                fos_Setting username = emailSettings.Where(a => a.Id == 6).FirstOrDefault();
                fos_Setting password = emailSettings.Where(a => a.Id == 7).FirstOrDefault();
                fos_Setting From = emailSettings.Where(a => a.Id == 2).FirstOrDefault();

                SmtpServer.Host = emailHost.ParamValue;
                SmtpServer.Port = Convert.ToInt32(emailPort.ParamValue);


                SmtpServer.Credentials = new System.Net.NetworkCredential(username.ParamValue, password.ParamValue);
                mail.From = new MailAddress(From.ParamValue);

                mail.IsBodyHtml = true;
                foreach (string a in to)
                    mail.To.Add(a);
                mail.Subject = subject;
                mail.Body = body;


                SmtpServer.EnableSsl = true;

                SmtpServer.Send(mail);

            }
            catch (Exception ex)
            {
                throw new Exception("Mail Server Error!" + ex.Message);
            }
        }

        /// <summary>
        /// check email validity
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        /// <summary>
        /// Regular expression, which is used to validate an E-Mail address.
        /// </summary>
        public const string MatchEmailPattern =
                  @"^(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))@"
           + @"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?
				[0-9]{1,2}|25[0-5]|2[0-4][0-9])\."
           + @"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?
				[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
           + @"([a-zA-Z]+[\w-]+\.)+[a-zA-Z]{2,4})$";

        /// <summary>
        /// Checks whether the given Email-Parameter is a valid E-Mail address.
        /// </summary>
        /// <param name="email">Parameter-string that contains an E-Mail address.</param>
        /// <returns>True, when Parameter-string is not null and 
        /// contains a valid E-Mail address;
        /// otherwise false.</returns>
        public static bool IsEmail(string email)
        {
            if (email != null) return Regex.IsMatch(email, MatchEmailPattern);
            else return false;
        }




        private static string _strRGBIV = "flexfood";
        private static string _cryptographyString = "ABCDE12345";

        /* Function to decrypt using the privateKey and text */
        public static string DecryptQueryString(string text)
        {
            string result = string.Empty;

            try
            {
                // decryptKey = decryptKey.Replace(" ", "+");
                //
                //text = text.Replace("AAA", "=");
                text = HttpUtility.UrlDecode(text);
                text = text.Replace(" ", "+");

                DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
                byte[] key = Encoding.UTF8.GetBytes(_cryptographyString.Substring(0, 8));
                byte[] inputByte = Convert.FromBase64String(text);
                byte[] rgbIV = Encoding.UTF8.GetBytes(_strRGBIV);
                MemoryStream memoryStream = new MemoryStream();
                CryptoStream cryptStream = new CryptoStream(memoryStream, provider.CreateDecryptor(key, rgbIV), CryptoStreamMode.Write);
                cryptStream.Write(inputByte, 0, inputByte.Length);
                cryptStream.FlushFinalBlock();
                Encoding encoding = Encoding.UTF8;
                result = encoding.GetString(memoryStream.ToArray());
            }
            catch (Exception e)
            {
                throw new Exception(e.InnerException.ToString());
            }
            return result;
        }

        /* Function to encrypt using the privateKey and text */
        public static string EncryptQueryString(string text)
        {
            string result = string.Empty;

            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            byte[] key = Encoding.UTF8.GetBytes(_cryptographyString.Substring(0, 8));

            byte[] inputByte = Encoding.UTF8.GetBytes(text);
            byte[] rgbIV = Encoding.UTF8.GetBytes(_strRGBIV);
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptStream = new CryptoStream(memoryStream, provider.CreateEncryptor(key, rgbIV), CryptoStreamMode.Write);
            cryptStream.Write(inputByte, 0, inputByte.Length);
            cryptStream.FlushFinalBlock();
            result = Convert.ToBase64String(memoryStream.ToArray());
            result = HttpUtility.UrlEncode(result);


            return result;
        }

        /* Function to decrypt using the privateKey and text */
        public static string DecryptQueryString(string decryptKey, string text)
        {
            string result = string.Empty;


            // decryptKey = decryptKey.Replace(" ", "+");
            text = text.Replace(" ", "+"); // variables passed through querystring replaces '+' with ' ' 
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            byte[] key = Encoding.UTF8.GetBytes(decryptKey.Substring(0, 8));
            byte[] inputByte = Convert.FromBase64String(text);
            byte[] rgbIV = Encoding.UTF8.GetBytes(_strRGBIV);
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptStream = new CryptoStream(memoryStream, provider.CreateDecryptor(key, rgbIV), CryptoStreamMode.Write);
            cryptStream.Write(inputByte, 0, inputByte.Length);
            cryptStream.FlushFinalBlock();
            Encoding encoding = Encoding.UTF8;
            result = encoding.GetString(memoryStream.ToArray());



            return result;
        }

        /* Function to encrypt using the privateKey and text */
        public static string EncryptQueryString(string encryptKey, string text)
        {
            string result = string.Empty;

            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            byte[] key = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
            byte[] inputByte = Encoding.UTF8.GetBytes(text);
            byte[] rgbIV = Encoding.UTF8.GetBytes(_strRGBIV);
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptStream = new CryptoStream(memoryStream, provider.CreateEncryptor(key, rgbIV), CryptoStreamMode.Write);
            cryptStream.Write(inputByte, 0, inputByte.Length);
            cryptStream.FlushFinalBlock();
            result = Convert.ToBase64String(memoryStream.ToArray());

            return result;
        }

        /* Function to encode password using MD5 method */
        public static string EncodePassword(string originalPassword)
        {
            //Declarations
            Byte[] originalBytes;
            Byte[] encodedBytes;
            MD5 md5;

            //Instantiate MD5CryptoServiceProvider, get bytes for original password and compute hash (encoded password)
            md5 = new MD5CryptoServiceProvider();
            originalBytes = ASCIIEncoding.Default.GetBytes(originalPassword);
            encodedBytes = md5.ComputeHash(originalBytes);

            //Convert encoded bytes back to a 'readable' string
            return Regex.Replace(BitConverter.ToString(encodedBytes).ToLower(), "-", "");
        }


        public static string GetFullUrl(string originalUrl)
        {
            if (originalUrl == null) return null;

            // *** Absolute path - just return
            if (originalUrl.IndexOf("://") != -1) return originalUrl;

            // *** Fix up image path for ~ root app dir directory
            if (originalUrl.StartsWith("~"))
            {
                string newUrl = "";
                if (HttpContext.Current != null)
                {
                    String appPath;
                    appPath = HttpContext.Current.Request.ApplicationPath;
                    char last = appPath[appPath.Length - 1];

                    if (last == '/')
                    {
                        if (appPath.Length > 1)
                        {
                            appPath = appPath.Substring(0, appPath.Length - 2);
                            newUrl = appPath + originalUrl.Substring(1).Replace("//", "/");
                        }
                        else
                        {
                            newUrl = originalUrl.Substring(1).Replace("//", "/");
                        }
                    }
                    else
                    {
                        newUrl = HttpContext.Current.Request.ApplicationPath + originalUrl.Substring(1).Replace("//", "/");
                    }
                }
                else
                {
                    throw new ArgumentException("Invalid URL: Relative URL not allowed.");
                }
                return "http://" + HttpContext.Current.Request.Headers["host"] + newUrl;
            }
            return "http://" + HttpContext.Current.Request.Headers["host"] + originalUrl;
        }



        public static byte[] convertImageSize(byte[] image)
        {

            if (!IsValidImage(image)) return image;

            ImageConverter ic = new ImageConverter();
            System.Drawing.Image imagedrawing = (System.Drawing.Image)ic.ConvertFrom(image);



            Bitmap startBitmap = new Bitmap(imagedrawing); ; // write CreateBitmapFromBytes  
            Bitmap newBitmap = new Bitmap(800, 600);
            using (Graphics graphics = Graphics.FromImage(newBitmap))
            {
                graphics.DrawImage(startBitmap, new Rectangle(0, 0, 800, 600), new Rectangle(0, 0, startBitmap.Width, startBitmap.Height), GraphicsUnit.Pixel);
            }

            var memStream = new MemoryStream();
            newBitmap.Save(memStream, ImageFormat.Jpeg);


            byte[] newBytes = memStream.ToArray();

            return newBytes;

        }

        public static bool IsValidImage(byte[] bytes)
        {
            try
            {
                using (MemoryStream ms = new MemoryStream(bytes))
                    Image.FromStream(ms);
            }
            catch (ArgumentException)
            {
                return false;
            }
            return true;
        }
    }


    public abstract class BaseDomainContext : DbContext
    {
        static BaseDomainContext()
        {
            // ROLA - This is a hack to ensure that Entity Framework SQL Provider is copied across to the output folder.
            // As it is installed in the GAC, Copy Local does not work. It is required for probing.
            // Fixed "Provider not loaded" error
            var ensureDLLIsCopied = System.Data.Entity.SqlServer.SqlProviderServices.Instance;
        }
    }
}
